#include "GLConsole.h"
template<> GLConsole* Singleton<GLConsole>::ms_Singleton = 0;


void GLConsole::SetOrtho()
{
	GLint viewport[4];
	glGetIntegerv(GL_VIEWPORT, viewport);

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	gluOrtho2D(0.0, (GLfloat) viewport[2], 0.0f, (GLfloat) viewport[3]);
	if(_startX < 0)
		_X = viewport[2] + _startX;
	if(_startY < 0)
		_Y = viewport[3] + _startY;

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();

	glLoadIdentity();

}


void GLConsole::UnSetOrtho()
{
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
}

GLConsole::GLConsole(int startX, int startY, int width, int height) : Singleton(), Renderable()
{
	_X = _startX = startX;
	_Y = _startY = startY;
	_width = width;
	_height = height;
	_selected = true;
	//dziwne ale glutBitmapHeight jest nie zaimplementowane, hmmmmm...
	_fontHeight = glutBitmapWidth(GLUT_BITMAP_HELVETICA_10, 'M') + 3;

	_lines.push_back("Adam Golan - 2008");
	_lines.push_back("Uniwersalny solver dla lancuchow kinematycznych 6DOF z trzema parami obrotowymi");
}

/* override */
void GLConsole::Render()
{

	SetOrtho();
	glDisable(GL_LIGHTING);
	glDisable(GL_DEPTH_TEST);	
	glEnable (GL_BLEND); 
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	//REND:
	_Y = _startY;
	glBegin(GL_QUADS);
	glColor4f(0.1, 0, 0.3, 0.5);	
	glVertex2d(_X, _Y);
	glVertex2d(_X + _width, _Y);
	glVertex2d(_X + _width, _Y - _height);
	glVertex2d(_X, _Y - _height);
	glEnd();



	int linesHeight = 0;

	while(true)
	{
		linesHeight = 0;
		_Y = _startY;
		for(int i = 0; i < _lines.size(); i++)
		{
			int curLineHeight = CountLineHeight((const char *)_lines[i].c_str());
			linesHeight += curLineHeight;
			_Y -= curLineHeight;
		}
		if(_Y > _startY - _height)
		{
			break;
		}
		else
		{
			if(_lines.size() > 0)
				_lines.erase(_lines.begin());
		}

	}
	_Y = _startY;
	linesHeight = 0;

	for(int i = 0; i < _lines.size(); i++)
	{
		int curLineHeight = RenderLine((const char *)_lines[i].c_str());
		linesHeight += curLineHeight;
		_Y -= curLineHeight;
		//if(_Y < _startY - _height)
		//{
		//	_lines.erase(_lines.begin());
		//	goto REND;
		//}
	}

	glEnable(GL_LIGHTING);
	glEnable(GL_DEPTH_TEST);
	glDisable(GL_BLEND);


	UnSetOrtho();
}

int GLConsole::CountLineHeight(const char *string)
{
	glRasterPos2i(_X, _Y);
	int x = _X;
	int y = _Y - _fontHeight;

	for (const char *c = string; *c != '\0'; c++) {	

		if(x + glutBitmapWidth(GLUT_BITMAP_HELVETICA_10,*c) - _X > _width)
		{
			y -= _fontHeight;
			x = _X;
		}
		x = x + glutBitmapWidth(GLUT_BITMAP_HELVETICA_10,*c) + 2;
	}
	return _Y - y;
}
int GLConsole::RenderLine(const char *string)
{
	glRasterPos2i(_X, _Y);
	int x = _X;
	int y = _Y - _fontHeight;
	glColor4f(1, 1, 0.8, 0.9);

	for (const char *c = string; *c != '\0'; c++) {	

		if(x + glutBitmapWidth(GLUT_BITMAP_HELVETICA_10,*c) - _X > _width)
		{
			y -= _fontHeight;
			x = _X;
		}
		glRasterPos2f(x, y);
		glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, *c);
		x = x + glutBitmapWidth(GLUT_BITMAP_HELVETICA_10,*c) + 2;



	}
	return _Y - y;
}
void GLConsole::PrintLine(char *arg)
{
	_lines.push_back(arg);
}
void GLConsole::PrintLine(std::string arg)
{
	_lines.push_back(arg);
}